comment |
   This program demonstrates how your BIOS translates your keystrokes, 
   with both new- and old-style calls to Int 16H.
   Save as:  Snoop16.ASM
   Compile:  MASM SNOOP16;
   	     LINK SNOOP16;

   If you use TASM, you must use the Quirks and MASM51 directives and
   expand the 3rd unnamed label (@@) and its reference to some alphabetic
   characters.
	|
		.MODEL SMALL,PASCAL
		.STACK
		.DATA
CR	=	13
LF	=	10
nobios	db	"You must have an Enhanced Keyboard (101/102 keys) and",CR,LF
	db	"a BIOS that supports extended keyboard services to",CR,LF
	db	"run this program.",CR,LF,'$'
scrndat	db	"Type any key or key combination to see",CR,LF
	db	"how it is treated by calls to old and",CR,LF
	db	"new services of Int 16h.",CR,LF
	db	CR,LF
	db	"    Press ESC to end",CR,LF
	db	CR,LF
	db	"=========================================",CR,LF
	db	"Buffer Code   New Services   Old Services",CR,LF
	db	"=========================================",CR,LF,'$'

linedat	db	"   "
bufdat	db	"0000H          "
newdat	db	"0000H          "
olddat	db	"0000H   $"
prntrow	db	9

lastkey	dw	?
hextbl	db	"0123456789ABCDEF"

		.CODE
print		macro	text
		mov	dx,offset text
		mov	ah,9
		int	21h
		endm

start:		mov	ax,@data
		mov	ds,ax
		call	bioscheck
		call	setscreen
lp:		call	getbufcode		;Get 1st entry in buffer
  		push	ax			;Save it
		mov	ah,11h			;Extended keybrd status
		int	16h			;Call kb services
		jnz	@F			;Go if key available
		sub	ax,ax			;Else AX = 0
  @@:		push	ax			;Save value
		mov	ah,01h			;Old keybrd status
		int	16h			;Call kb services
		jnz	@F			;Go if key available
		sub	ax,ax			;Else AX = 0
  @@:		push	ax			;Save value
		mov	[lastkey],ax		;  and save again
		jz	@F			;No key -- jump ahead
		mov	ah,0			;Old kb read
		int	16h			;Get & discard value
  @@:		call	printvals		;Print saved values
		cmp	[lastkey],011bh		;Was it escape?
		jne	lp			;No -- do it again
		mov	ax,4c00h		;Else exit
		int	21h			;That's the end

bioscheck	proc	near
		mov	ax,40h			;Segment of BIOS data
		mov	es,ax			;Into ES
		test	byte ptr es:[96h],10h	;Bit 4 on?
		jnz	@F			;Yes -- skip ahead
		print	nobios			;Else print error
		mov	ax,4cffh		;And exit
		int	21h
  @@:		ret
bioscheck	endp

setscreen	proc	near
		mov	ah,0fh			;Get video mode
		int	10h			;Call video services
		mov	ah,0			;Set mode in AL
		int	10h			;Now screen is clear
		print	scrndat			;Print opening message
		ret
setscreen	endp

getbufcode	proc	near
		mov	ax,40h			;Segment of BIOS data
		mov	es,ax			;ES==> BIOS data
  @@:		mov	si,word ptr es:[1ah]	;KB buffer head in SI
  		mov	di,word ptr es:[1ch]	;KB buffer tail in DI
		cmp	si,di			;Are they the same?
		jz	@B			;Yes -- wait
		mov	ax,es:[si]		;Else get word at start
		ret				;And return it in AX
getbufcode	endp

printvals	proc	near  bufval, newval, oldval
		mov	bh,0	  		;On page 0
		mov	dh,prntrow		;Set cursor row
		mov	dl,0			;Column 0
		mov	ah,2			;Set cursor posn
		int	10h			;Call video services

		push	ds
		pop	es			;ES ==> data seg also

		mov	bx,offset hextbl	;BX ==> translation table
		mov	ax,bufval		;Get buffer value
		mov	di,offset bufdat	;DI ==> output buffer
		call	bin2hex			;Translate to ASCII hex
		mov	ax,newval		;Get next data item
		mov	di,offset newdat	;Point to new buffer
		call	bin2hex			;Translate it
		mov	ax,oldval		;Same for last data item
		mov	di,offset olddat
		call	bin2hex
		print	linedat			;Now print everything
		ret
printvals	endp

bin2hex		proc	near			;Entry: BX ==> hextable
						; AX = word value
						; ES:DI ==> string posn
		push	ax			;Save value
		mov	al,ah			;High byte in AL & AH
		mov	cl,4			;Bits to shift
		shr	al,cl			;Isolate high nibble
		xlat	[bx]			;Get hex character
		stosb				;Save in string
		mov	al,ah			;Get original value
		and	al,0fh			;Isolate low nibble
		xlat	[bx]			;Get hex character
		stosb				;Save in string
		pop	ax			;Get original value
		mov	ah,al			;Copy low byte
		mov	cl,4			;Bits to shift
		shr	al,cl			;Isolate high nibble
		xlat	[bx]			;Get hex character
		stosb				;Save in string
		mov	al,ah			;Get original value
		and	al,0fh			;Isolate low nibble
		xlat	[bx]			;Get hex character
		stosb				;Save in string
		ret
bin2hex		endp
		end 	start
		
